//------------------------------------------------------------------------------
// GenericI2CTypes.cs
//
// This is a generic contract that can be implemented by vendor specific
// I2C components so as to allow access to the I2C bus.
//
// Implementations exist for the Devanctech USBI2C / Devantech RF03 and 
// Robotics Connection Serializer
//
//------------------------------------------------------------------------------
using Microsoft.Ccr.Core;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.Core.Attributes;
using System;
using System.ComponentModel;
using W3C.Soap;

namespace Generic.Protocols.I2C
{
    #region Contract
    /// <summary>
    /// Generic I2C contract
    /// </summary>
    [DisplayName("Generic I2C")]
    [Description("A generic contract implemented by specific I2CHardware")]
    public sealed class Contract
    {
         /// <summary>
         /// GenericI2C contract Identifier
         /// </summary>
        [DataMember]
        public const String Identifier = "http://www.tempuri.com/2006/10/generici2c.html";
    }
    #endregion

    #region State

    /// <summary>
    /// The GenericI2C State
    /// </summary>
    [DataContract()]
    public class GenericI2CState
    {
        private string _description = "This is a generic service with no state";

        /// <summary>
        /// Description
        /// </summary>
        [DataMember]
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }
    }
    #endregion

    #region Operations
    /// <summary>
    /// Operations Port for the GenericI2C class
    /// </summary>
    [ServicePort]
    public class GenericI2COperations : PortSet<
        DsspDefaultLookup,
        DsspDefaultDrop,
        Get,
        ReadData,
        WriteData>
    {
    }
    #endregion

    #region Messages
    /// <summary>
    /// Gets the state of the GenericI2C
    /// </summary>
    public class Get : Get<GetRequestType, PortSet<GenericI2CState, Fault>>
    {
        /// <summary>
        /// MijnGeneric Get Operation
        /// </summary>
        public Get()
        {
        }

        /// <summary>
        /// MijnGeneric Get Operation
        /// </summary>
        public Get(Microsoft.Dss.ServiceModel.Dssp.GetRequestType body) :
            base(body)
        {
        }

        /// <summary>
        /// MijnGeneric Get Operation
        /// </summary>
        public Get(Microsoft.Dss.ServiceModel.Dssp.GetRequestType body, Microsoft.Ccr.Core.PortSet<GenericI2CState, W3C.Soap.Fault> responsePort) :
            base(body, responsePort)
        {
        }
    }

    /// <summary>
    /// Reads data from the I2C Bus
    /// </summary>
    [Description("Reads data from the I2C bus")]
    public class ReadData : Update<ReadDataRequest, PortSet<ReturnData, Fault>>
    {
        /// <summary>
        /// 
        /// </summary>
        public ReadData()
            : base(new ReadDataRequest())
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="rd"></param>
        public ReadData(ReadDataRequest rd)
        {
            Body = rd;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i2cAddress"></param>
        /// <param name="registerAddress"></param>
        /// <param name="numBytes"></param>
        public ReadData(byte i2cAddress, byte registerAddress, int numBytes)
        {
            Body.I2CAddress = i2cAddress;
            Body.RegisterAddress = registerAddress;
            Body.NumBytes = numBytes;
        }
    }

    /// <summary>
    /// Writes data to the I2C bus
    /// </summary>
    [Description("Writes data to the I2C bus")]
    public class WriteData : Update<WriteDataRequest, PortSet<DefaultUpdateResponseType, Fault>>
    {
        /// <summary>
        /// 
        /// </summary>
        public WriteData()
            : base(new WriteDataRequest())
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writeDataRequest"></param>
        public WriteData(WriteDataRequest writeDataRequest)
        {
            Body = writeDataRequest;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i2cAddress"></param>
        /// <param name="registerAddress"></param>
        /// <param name="data"></param>
        public WriteData(byte i2cAddress, byte registerAddress, byte[] data)
        {
            Body.I2CAddress = i2cAddress;
            Body.RegisterAddress = registerAddress;
            Body.Data = data;
        }
    }


    /// <summary>
    /// The body of the ReadData method
    /// </summary>
    [DataContract]
    [Description("The body of the ReadData method")]
    public class ReadDataRequest
    {
        private byte _i2cAddress;
        private byte _registerAddress;
        private int _numBytes;

        /// <summary>
        /// The I2C Address of the device you want to read from
        /// </summary>
        [DataMember]
        [Description("The I2C Address of the device you want to read from")]
        public byte I2CAddress
        {
            get { return _i2cAddress; }
            set { _i2cAddress = value; }
        }
        
        /// <summary>
        /// The register address that you want to begin reading from
        /// </summary>
        [DataMember]
        [Description("The register address that you want to begin reading from")]
        public byte RegisterAddress
        {
            get { return _registerAddress; }
            set { _registerAddress = value; }
        }

        /// <summary>
        /// The number of bytes that you want to read
        /// </summary>
        [DataMember]
        [Description("The number of bytes that you want to read")]
        public int NumBytes
        {
            get { return _numBytes; }
            set { _numBytes = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public ReadDataRequest() 
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="i2cAddress"></param>
        /// <param name="registerAddress"></param>
        /// <param name="numBytes"></param>
        public ReadDataRequest(byte i2cAddress, byte registerAddress, int numBytes)
        {
            _i2cAddress = i2cAddress;
            _registerAddress = registerAddress;
            _numBytes = numBytes;
        }
    }

    /// <summary>
    /// The body of the write data method
    /// </summary>
    [DataContract]
    [Description("The body of the write data method")]
    public class WriteDataRequest
    {
        private byte _i2cAddress;
        private byte _registerAddress;
        private byte[] _data;

        /// <summary>
        /// The I2C Address that you want to write to
        /// </summary>
        [DataMember]
        [Description("The I2C Address that you want to write to")]
        public byte I2CAddress
        {
            get { return _i2cAddress; }
            set { _i2cAddress = value; }
        }

        /// <summary>
        /// The register address that you want to write to
        /// </summary>
        [DataMember]
        [Description("The register address that you want to write to")]
        public byte RegisterAddress
        {
            get { return _registerAddress; }
            set { _registerAddress = value; }
        }

        /// <summary>
        /// The data that you want to write
        /// </summary>
        [DataMember]
        [Description("The data that you want to write")]
        public byte[] Data
        {
            get { return _data; }
            set { _data = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public WriteDataRequest() 
        { 
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i2cAddress"></param>
        /// <param name="registerAddress"></param>
        /// <param name="data"></param>
        public WriteDataRequest(byte i2cAddress, byte registerAddress, byte[] data)
        {
            _i2cAddress = i2cAddress;
            _registerAddress = registerAddress;
            _data = data;
        }
    }

    /// <summary>
    /// The body of the response to the read data method
    /// </summary>
    [DataContract]
    [Description("The body of the response to the read data method")]
    public class ReturnData
    {
        private byte[] _data;

        /// <summary>
        /// The data returned from a ReadData operation
        /// </summary>
        [DataMember]
        [Description("The data returned from a ReadData operation")]
        public byte[] Data
        {
            get { return _data; }
            set { _data = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public ReturnData() 
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        public ReturnData(byte[] data)
        {
            _data = data;
        }
    }
    #endregion
}